#ifndef PUZZLE_PATH_H_
#define PUZZLE_PATH_H_

// INCLUDES //
#include "path.h"
//////////////

/// The delay between each horizontal shift.
const int KEY_DELAY = 70;

/**
* A listener to the events of a PuzzlePath
* 
* @see PuzzlePath
* @author dfoelber
**/
class PuzzlePathListener
{
public:
	/**
	* Virtual destructor
	**/
	virtual ~PuzzlePathListener() {}
	
	/**
	* Invoked when the puzzle path has finished dropping.
	**/
	virtual void PuzzlePathFinished() = 0;
};

/**
* A path that slowly falls and can be shifted side to side.
* 
* @see PuzzlePathListener
* @author dfoelber
**/
class PuzzlePath : public Path
{
public:
	/// The possible commands
	enum PuzzlePathCommands
	{
		COMMAND_DROP = 32,
		COMMAND_ROTATE = 64
	};
	
public:
	/**
	* Constructor
	* 
	* @param width The width of the puzzle piece
	* @param initialYVel Velocity of the path's falling
	**/
	PuzzlePath( int width, double initialYVel = 0.5 );
	
	/**
	* Sets the path's listener
	* 
	* @param listener The new listener
	**/
	void SetListener( PuzzlePathListener* listener );
	
	/**
	* Notifies the path that an event has occurred.
	* 
	* Overridden from Path.
	* 
	* @param event The event that occurred
	**/
	virtual void PuzzleEventOccurred( PuzzleEvent event );
	
	/**
	* Lets the path know that time has passed and to move accordingly.
	* 
	* Overridden from Path.
	* 
	* @param ms The time passed since last called
	**/
	virtual void TimePassed( int ms );
	
	/**
	* Input that can be used by the path.
	* 
	* Overridden from Path.
	* 
	* @param event The event
	* @return If the event was consumed
	**/
	virtual bool Input( SDL_Event event );
	
	/**
	* Check if this path collided with another path.
	* 
	* Overridden from Path.
	* 
	* @param other The other path's area.
	* @param xDistance The other path's X distance.
	* @param yDistance The other path's Y distance.
	* 
	* @return If collided 
	**/
	virtual bool CheckCollision( Area* other, double xDistance, double yDistance );
	
	/**
	* Sets the position of the path.
	* 
	* Overridden from Path.
	* 
	* @param x The new X coordinate
	* @param y The new Y coordinate
	**/
	virtual void SetPosition( int x, int y );
	
	/**
	* Gets if the path is still moving.
	* 
	* Overridden from Path.
	* 
	* @return If the path is moving
	**/
	virtual bool IsMoving();
	
	/**
	* Gets the Y velocity of the path.
	* 
	* Overridden from Path.
	* 
	* @return The current Y velocity
	**/
	virtual double GetYVel() const;
	
	/**
	* Advances the path, applying its x and y distances.
	* 
	* Overridden from Path.
	**/
	virtual void Advance()
	{
		rotate = false;
		Path::Advance();
	}
	
private:
	/// The puzzle path's listener.
	PuzzlePathListener*	listener;
	/// The stored key direction, used for horizontal delay.
	Direction			oldDir;
	/// The counter that holds the counted down delay.
	int					delayCounter;
	/// The width of the puzzle piece.
	int 				width; 
	/// If the puzzle path is in the process of rotating.
	bool				rotate;
	/// The base V velocity
	double				baseYVel;
};

#endif /*PUZZLE_PATH_H_*/
